package com.gw.utils;

import io.minio.*;
import io.minio.errors.*;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.UUID;

@Component
@Data
@Slf4j
public class MinioUtil {

    private String endpoint = "http://localhost:9000";
    private String accessKey = "05Wt8tl0tUaLjPgIgFui"; //"GwIG4AbscC0Kpf7UDeQh";

    private String secretKey =  "y0AnvCZ2UuJPdcEuRzpRkkOiizinNt5aQQfxLXbd"; //"6iCAHAH6rzO8gr1Y5QG8tuKJmL4rKKmzgu7s8Hmc";

    //创建一个minio客户端
    private MinioClient minioClient =
            MinioClient.builder()
                    .endpoint(endpoint)
                    .credentials(accessKey, secretKey)
                    .build();

    /**
     * 文件上传
     * @param multipartFile 文件
     * @param buketName 桶名
     * @return 文件访问路径
     */
    public String  upload(MultipartFile multipartFile, String buketName) {
        //文件判空
        if (multipartFile.isEmpty()) {
            throw new RuntimeException("文件为空，不可上传！");
        }

        //截取原始文件后缀
        String extName = null;
        if (multipartFile.getOriginalFilename() != null) {
            extName = multipartFile.getOriginalFilename().substring(multipartFile.getOriginalFilename().lastIndexOf("."));
        }

        //构造新文件名称
        String objectName = UUID.randomUUID() + extName;

        try (InputStream inputStream = multipartFile.getInputStream()) {
            //判断桶是否存在
            boolean found =
                    minioClient.bucketExists(BucketExistsArgs.builder().bucket(buketName).build());
            if (!found) {
                //如果不存在创建一个新桶
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(buketName).build());
                log.info("桶{}不存在，现在创建该桶..", buketName);
            }
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(buketName)//桶名
                            .object(objectName)//文件名
                            .contentType(multipartFile.getContentType())//源文件type
                            .stream(inputStream, multipartFile.getSize(), -1)
                            .build());

            log.info("文件{}上传成功", multipartFile.getOriginalFilename());
        } catch (IOException | NoSuchAlgorithmException | InvalidKeyException | ErrorResponseException |
                 InsufficientDataException | InternalException | InvalidResponseException | ServerException |
                 XmlParserException e) {
            throw new RuntimeException(e);
        }
        return endpoint+'/' + buketName + '/' + objectName;
    }


    /**
     * 创建桶
     * @param bucketName
     */
    public void makeBucket(String bucketName){
        // 设置存储桶策略为 public
        String policy = "{\n" +
                "  \"Version\": \"2012-10-17\",\n" +
                "  \"Statement\": [\n" +
                "    {\n" +
                "      \"Effect\": \"Allow\",\n" +
                "      \"Principal\": \"*\",\n" +
                "      \"Action\": [\n" +
                "        \"s3:GetObject\"\n" +
                "      ],\n" +
                "      \"Resource\": [\n" +
                "        \"arn:aws:s3:::" + bucketName + "/*\"\n" +
                "      ]\n" +
                "    }\n" +
                "  ]\n" +
                "}";
        // 创建桶
        try {
            minioClient.makeBucket(
                    MakeBucketArgs.builder()
                            .bucket(bucketName)
                            .build());
            // 设置桶的访问权限
            minioClient.setBucketPolicy(
                    SetBucketPolicyArgs.builder()
                            .bucket(bucketName)
                            .config(policy)
                            .build()
            );
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 删除桶
     * @param bucketName
     */
    public void removeBucket(String bucketName){
        try {
            minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    //TODO 设计一个工具方法，删除对应帖子中的附件
}
